package org.everyday;

import java.util.*;

/**
 * @version v1.0.0
 * 创建时间：2022/7/6 11:51
 */
public class L736 {
    int start = 0;
    // 变量名-> 作用域列表，每当重新赋值则列表+1，当退出一个（），去掉里面的作用域最后一个
    Map<String,ArrayDeque<Integer>> scope = new HashMap<>();

    public int evaluate(String expression) {
        // 解析的没有(开始,只有可能是变量或者常量
        if (expression.charAt(start)!='('){
            if (Character.isLowerCase(expression.charAt(start))){
                // 解析变量
                String val = parseVar(expression);
                return scope.get(val).peek();
            }else {
                // 解析常量
                return parseInt(expression);
            }
        }
        start++;// 去掉（
        int ret = 0;
        // 分治处理表达式
        if (expression.charAt(start)=='l'){
            start += 4; // 移除 "let "
            List<String> vars = new ArrayList<String>();
            while (true) {
                // let最后的expr是一个新的表达式
                if (!Character.isLowerCase(expression.charAt(start))) {
                    ret = evaluate(expression); // let 表达式的最后一个 expr 表达式的值
                    break;
                }
                // 解析let的一对 v e
                String var = parseVar(expression);
                if (expression.charAt(start) == ')') {
                    ret = scope.get(var).peek(); // let 表达式的最后一个 expr 表达式的值
                    break;
                }
                start++; // 移除空格
                vars.add(var);
                int e = evaluate(expression);
                scope.putIfAbsent(var, new ArrayDeque<Integer>());
                scope.get(var).push(e);
                start++; // 移除空格
            }
            for (String var : vars) {
                scope.get(var).pop(); // 清除当前作用域的变量
            }
        } else if (expression.charAt(start) == 'a') {
            start += 4; // 移除 "add "
            int i = evaluate(expression);
            start++;
            int j = evaluate(expression);
            ret = i + j;
        } else if (expression.charAt(start) == 'm') {
            start += 5; // 移除 "mult "
            int e1 = evaluate(expression);
            start++; // 移除空格
            int e2 = evaluate(expression);
            ret = e1 * e2;
        }
        start++; // 移除右括号
        return ret;
    }

    private int parseInt(String ex){
        int n = ex.length();
        int ret = 0, sign = 1;
        if (ex.charAt(start) == '-') {
            sign = -1;
            start++;
        }
        while (start<n && Character.isDigit(ex.charAt(start))){
            ret = ret*10 + (ex.charAt(start)-'0');
            start++;
        }
        return ret * sign;
    }

    private String parseVar(String ex){
        int n = ex.length();
        StringBuffer ret = new StringBuffer();
        while (start < n
                && ex.charAt(start) != ' '
                && ex.charAt(start) != ')') {
            ret.append(ex.charAt(start));
            start++;
        }
        return ret.toString();
    }

    public static void main(String[] args) {
        new L736().evaluate("(let x 2 (mult x (let x 3 y 4 (add x y))))");
    }
}
